﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using IsmlTools.Common;
using IsmlTools.Dal.SQL;
using IsmlTools.Model;
using IsmlTools.Service;
using RegMatch = System.Text.RegularExpressions.Match;
using Match = IsmlTools.Dal.SQL.Match;


namespace IsmlTools.Bil
{
    public class PreliminaryResult : IResultManager
    {
        private WebHelper _webhelper = null;
        private RegHelper _reghelper = null;
        private NameHelper _namehelper = null;

        public void SaveResult()
        {
            SavePreliminaryPhaseI2012(CalendarHelper.PreliminaryPhaseIDate2012);
            SavePreliminaryPhaseIi2012(CalendarHelper.PreliminaryPhaseIDate2012);
        }

        private void SavePreliminaryPhaseIi2012(DateTime dateTime)
        {
            using (ISMLEntities db = new ISMLEntities())
            {
                try
                {
                    _namehelper = new NameHelper();

                    string[] days = GetAllDays(WebPageLink.PreliminaryPhaseIi2012, 2012);

                    Period period = new Period { Name = "Preliminary Phase 2", SeasonID = 5, PeriodTypeID = null };

                    Dictionary<string, string> seasonName = _namehelper.GetSeasonName(db, (int)period.SeasonID);

                    foreach (string day in days)
                    {
                        string gender, age, title;
                        string[] matches = GetAllMatches(out title, day, out gender, out age);

                        Round round = new Round { Name = title, Date = dateTime };
                        dateTime = CalendarHelper.GetNextDate(dateTime);

                        foreach (string matchstring in matches)
                        {
                            List<MatchInfo> matchinfos = GetMatchPreliminaryPhaseIi2012(matchstring);

                            foreach (MatchInfo matchinfo in matchinfos)
                            {

                                Match match = new Match
                                    {
                                        Name = matchinfo.Name,
                                        Map = matchinfo.MapUrl,
                                        Chart = matchinfo.ChartUrl
                                    };

                                foreach (var v in matchinfo.IdVoteMapping)
                                {
                                    if (seasonName.ContainsKey(v.Key.ToString()))
                                    {
                                        Vote vote = new Vote
                                            {
                                                SeasonNameCode = v.Key,
                                                Value = v.Value,
                                                Name = seasonName[v.Key.ToString()]
                                            };

                                        match.Votes.Add(vote);
                                    }
                                }
                                round.Matches.Add(match);
                            }
                        }

                        period.Rounds.Add(round);
                        db.Periods.Add(period);
                    }

                    db.SaveChanges();
                }
                catch (Exception ex)
                {

                }
            }
        }

        private void SavePreliminaryPhaseI2012(DateTime dateTime)
        {
            using (ISMLEntities db = new ISMLEntities())
            {
                try
                {
                    _namehelper = new NameHelper();

                    string[] days = GetAllDays(WebPageLink.PreliminaryPhaseI2012, 2012);

                    Period period = new Period { Name = "Preliminary Phase 1", SeasonID = 5, PeriodTypeID = null };

                    Dictionary<string, string> seasonName = _namehelper.GetSeasonName(db, (int)period.SeasonID);

                    foreach (string day in days)
                    {
                        string gender, age, title;
                        string[] matches = GetAllMatches(out title, day, out gender, out age);

                        Round round = new Round { Name = title, Date = dateTime};
                        dateTime = CalendarHelper.GetNextDate(dateTime);

                        foreach (string matchstring in matches)
                        {
                            MatchInfo matchinfo = GetMatch(matchstring);

                            Match match = new Match
                            {
                                Name = matchinfo.Name,
                                Map = matchinfo.MapUrl,
                                Chart = matchinfo.ChartUrl
                            };

                            foreach (var v in matchinfo.IdVoteMapping)
                            {
                                if (seasonName.ContainsKey(v.Key.ToString()))
                                {
                                    Vote vote = new Vote
                                    {
                                        SeasonNameCode = v.Key,
                                        Value = v.Value,
                                        Name = seasonName[v.Key.ToString()]
                                    };

                                    match.Votes.Add(vote);
                                }
                            }
                            round.Matches.Add(match);
                        }

                        period.Rounds.Add(round);
                        db.Periods.Add(period);
                    }

                    db.SaveChanges();
                }
                catch (Exception ex)
                {

                }
            }
        }

        public string[] GetAllDays(string pageLink, int year)
        {
            _webhelper = new WebHelper();

            string page = _webhelper.ReadPage(pageLink);
            switch (year)
            {
                case 2012:
                    page = page.Replace("</td></tr></table>\r\n   </td>\r\n  </tr></table>\r\n<br/>\r\n<table class='mauto'>", "</td></tr></table>\r\n   </td><td>\r\n   </td><td>\r\n   </td>\r\n  </tr></table><br/>\r\n<table class='mauto'>");
                    break;
                case 2013:
                    break;
                default:
                    break;

            }
            string[] days = Regex.Split(page, @"<div class='bg block periodB ball10 c mt10'>").Skip(1).ToArray();
            days[days.Length - 1] = Regex.Split(days[days.Length - 1], @"</div>  <!--close content-->").First();
            return days;
        }

        public string[] GetAllMatches(out string title, string day, out string gender, out string age)
        {
            gender = string.Empty;
            age = string.Empty;
            title = string.Empty;

            _reghelper = new RegHelper();

            string[] matches = (Regex.Split(day, @"</td>(?:[^<]|<(?!/td))+class='gCell' valign='top'>")).Where(x => x.StartsWith("\r\n")).ToArray();

            RegMatch match = Regex.Match(matches[0], _reghelper.GetMidPattern("<h2 class='c'>", "</h2>"));
            title = match.Success ? match.Groups[0].Value : string.Empty;

            matches[0] = Regex.Split(matches[0], @"class='gCell' valign='top'>")[1];

            string[] areagenderage = Regex.Split(matches[matches.Length - 1], @"<table class='mauto'><tr>");
            matches[matches.Length - 1] = areagenderage[0].Replace("\r\n   </td>\r\n  </tr></table><br/>\r\n", string.Empty);
            matches[matches.Length - 1] =
                matches[matches.Length - 1].Replace("\r\n   </td>\r\n  </tr></table>\r\n </div>\r\n</div>", string.Empty);
            matches[matches.Length - 1] = matches[matches.Length - 1].Replace("\r\n   </td><td>\r\n   </td>\r\n  </tr></table>\r\n<br/>\r\n", string.Empty);
            
            try
            {
                gender = areagenderage[1];
                age = areagenderage[2].Replace(@"</div>\r\n</div>", string.Empty);
            }
            catch (Exception ex)
            {
                gender = string.Empty;
                age = string.Empty;
            }

            return matches;
        }

        public MatchInfo GetMatch(string source)
        {
            _reghelper = new RegHelper();
            MatchInfo matchinfo = new MatchInfo();

            string[] lines = Regex.Split(source, @"</tr></table>\r\n");

            RegMatch match = Regex.Match(lines[0], _reghelper.GetMidPattern("<h2 class='periodB'>", "</h2>"));
            matchinfo.Name = match.Success ? match.Groups[0].Value : string.Empty;
            matchinfo.IdVoteMapping = new Dictionary<int, int>();
            for (int i = 0; i < lines.Length - 2; i++)
            {
                RegMatch m = Regex.Match(lines[i], _reghelper.GetMidPattern("<td class='l'><span id='c", "'>"));
                int id = m.Success ? int.Parse(m.Groups[0].Value) : -1;
                m = Regex.Match(lines[i], _reghelper.GetMidPattern("<td class='nLabel r'>", "</td>"));
                int vote = m.Success ? int.Parse(m.Groups[0].Value) : -1;
                matchinfo.IdVoteMapping.Add(id, vote);
            }

            match = Regex.Match(lines[lines.Length - 2], _reghelper.GetMidPattern("href='", "'"));

            matchinfo.MapUrl = match.Success ? match.Groups[0].Value : string.Empty;
            if (matchinfo.MapUrl == string.Empty)
            {
                match = Regex.Match(lines[lines.Length - 1], _reghelper.GetMidPattern("href='", "'"));
                matchinfo.MapUrl = match.Success ? match.Groups[0].Value : string.Empty;
            }

            match = Regex.Match(lines[lines.Length - 2], _reghelper.GetMidPattern("<br/><a href='", "'"));
            matchinfo.ChartUrl = match.Success ? match.Groups[0].Value : string.Empty;

            if (matchinfo.ChartUrl == string.Empty)
            {
                match = Regex.Match(lines[lines.Length - 1], _reghelper.GetMidPattern("<br/><a href='", "'"));
                matchinfo.ChartUrl = match.Success ? match.Groups[0].Value : string.Empty;
            }

            return matchinfo;
        }

        public List<MatchInfo> GetMatchPreliminaryPhaseIi2012(string source)
        {
            _reghelper = new RegHelper();
            List<MatchInfo> matchInfos = new List<MatchInfo>();

            string[] matches = Regex.Split(source, "<hr class='short period' size='1' style='margin: 5px auto;'></hr>");


            string name = string.Empty;

            foreach (string match in matches) {
                MatchInfo matchinfo = new MatchInfo();
                string[] lines = Regex.Split(match, @"</tr></table>\r\n");
                RegMatch regmatch = null;

                if (string.IsNullOrEmpty(name))
                {
                    regmatch = Regex.Match(lines[0], _reghelper.GetMidPattern("<h2 class='periodB'>", "</h2>"));
                    matchinfo.Name = regmatch.Success ? regmatch.Groups[0].Value : string.Empty;
                    name = matchinfo.Name;
                }
                else
                    matchinfo.Name = name;
                matchinfo.IdVoteMapping = new Dictionary<int, int>();
                for (int i = 0; i < lines.Length - 2; i++)
                {
                    RegMatch m = Regex.Match(lines[i], _reghelper.GetMidPattern("<td class='l'><span id='c", "'>"));
                    int id = m.Success ? int.Parse(m.Groups[0].Value) : -1;
                    m = Regex.Match(lines[i], _reghelper.GetMidPattern("<td class='nLabel r'>", "</td>"));
                    int vote = m.Success ? int.Parse(m.Groups[0].Value) : -1;
                    matchinfo.IdVoteMapping.Add(id, vote);
                }

                regmatch = Regex.Match(lines[lines.Length - 2], _reghelper.GetMidPattern("href='", "'"));

                matchinfo.MapUrl = regmatch.Success ? regmatch.Groups[0].Value : string.Empty;
                if (matchinfo.MapUrl == string.Empty)
                {
                    regmatch = Regex.Match(lines[lines.Length - 1], _reghelper.GetMidPattern("href='", "'"));
                    matchinfo.MapUrl = regmatch.Success ? regmatch.Groups[0].Value : string.Empty;
                }

                regmatch = Regex.Match(lines[lines.Length - 2], _reghelper.GetMidPattern("<br/><a href='", "'"));
                matchinfo.ChartUrl = regmatch.Success ? regmatch.Groups[0].Value : string.Empty;

                if (matchinfo.ChartUrl == string.Empty)
                {
                    regmatch = Regex.Match(lines[lines.Length - 1], _reghelper.GetMidPattern("<br/><a href='", "'"));
                    matchinfo.ChartUrl = regmatch.Success ? regmatch.Groups[0].Value : string.Empty;
                }

                matchInfos.Add(matchinfo);
            }

            return matchInfos;
        }
    }
}
